#include "drv_soft_iic.h"
#include "delay.h"
#include <stdio.h>

#define DRV_MAX_IIC_BUS_NUM			5
struct drv_i2c_device{
	uint32_t scl_pin;
	uint32_t sda_pin;
	uint8_t  regsitered;
};

static struct drv_i2c_device drv_i2c_bus[DRV_MAX_IIC_BUS_NUM] = {
	{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}
};

static void DRV_IIC_SCL_SET(uint32_t index){
	if(index >= 5){
		printf("i2c buf index error,index = %d\n",index);
	}
	hc32_pin_write(drv_i2c_bus[index].scl_pin,PIN_HIGH);
}

static void DRV_IIC_SCL_CLR(uint32_t index){
	if(index >= 5){
		printf("i2c buf index error,index = %d\n",index);
	}
	hc32_pin_write(drv_i2c_bus[index].scl_pin,PIN_LOW);
}

static void DRV_IIC_SDA_IN(uint32_t index){
	if(index >= 5){
		printf("i2c buf index error,index = %d\n",index);
	}
	hc32_pin_mode(drv_i2c_bus[index].sda_pin,PIN_MODE_INPUT_PULLUP);
}

static void DRV_IIC_SDA_OUT(uint32_t index){
	if(index >= 5){
		printf("i2c buf index error,index = %d\n",index);
	}
	hc32_pin_mode(drv_i2c_bus[index].sda_pin,PIN_MODE_OUTPUT);
}

static void DRV_IIC_SDA_SET(uint32_t index){
	if(index >= 5){
		printf("i2c buf index error,index = %d\n",index);
	}
	hc32_pin_write(drv_i2c_bus[index].sda_pin,PIN_HIGH);
}

static void DRV_IIC_SDA_CLR(uint32_t index){
	if(index >= 5){
		printf("i2c buf index error,index = %d\n",index);
	}
	hc32_pin_write(drv_i2c_bus[index].sda_pin,PIN_LOW);
}

static uint8_t DRV_IIC_SDA_READ(uint32_t index){
	if(index >= 5){
		printf("i2c buf index error,index = %d\n",index);
	}
	return hc32_pin_read(drv_i2c_bus[index].sda_pin);
}

static void DRV_IIC_START(uint8_t x){
									
	DRV_IIC_SDA_OUT(x);
	DRV_IIC_SDA_SET(x);
	DRV_IIC_SCL_SET(x);
	Delay_us(8);
	DRV_IIC_SDA_CLR(x);
	Delay_us(8);
	DRV_IIC_SCL_CLR(x);
}

static void DRV_IIC_STOP(uint8_t x)		{
	
	DRV_IIC_SDA_OUT(x);
	DRV_IIC_SCL_CLR(x);
	DRV_IIC_SDA_CLR(x);	
	Delay_us(8);
	DRV_IIC_SCL_SET(x);
	DRV_IIC_SDA_SET(x);
	Delay_us(8);
}

static uint8_t DRV_IIC_Wait_Ack(uint8_t x)		{			
	uint8_t ErrTime=0;							
	DRV_IIC_SDA_IN(x);				
	DRV_IIC_SDA_SET(x);				
	Delay_us(3);					
	DRV_IIC_SCL_SET(x);				
	Delay_us(3);					
	while(DRV_IIC_SDA_READ(x)){			
		ErrTime++;					
		if(ErrTime>250){			
			DRV_IIC_STOP(x);		
			return 1;				
		}							
	}								
	DRV_IIC_SCL_CLR(x);						
	return 0;						
}

static void DRV_IIC_Ack(uint8_t x){
	
	DRV_IIC_SCL_CLR(x);
	DRV_IIC_SDA_OUT(x);
	DRV_IIC_SDA_CLR(x);
	Delay_us(2);
	DRV_IIC_SCL_SET(x);
	Delay_us(2);
	DRV_IIC_SCL_CLR(x);
}

static void DRV_IIC_NAck(uint8_t x){
	
	DRV_IIC_SCL_CLR(x);
	DRV_IIC_SDA_OUT(x);
	DRV_IIC_SDA_SET(x);
	Delay_us(2);
	DRV_IIC_SCL_SET(x);
	Delay_us(2);
	DRV_IIC_SCL_CLR(x);
}

 
static void DRV_IIC_SEND_BYTE(uint8_t x,uint8_t dat){
	uint8_t t;
	DRV_IIC_SDA_OUT(x);
	DRV_IIC_SCL_CLR(x);
	for(t=0;t<8;t++){
		if(dat&0x80){
			DRV_IIC_SDA_SET(x);
		}
		else{  
			DRV_IIC_SDA_CLR(x);
		}
		Delay_us(5);
		DRV_IIC_SCL_SET(x);
		Delay_us(5);
		DRV_IIC_SCL_CLR(x);
		dat<<=1;
		Delay_us(5);
	}
}

static uint8_t DRV_IIC_READ_BYTE(uint8_t x,uint8_t ack){
	uint8_t i,receive=0;
	DRV_IIC_SDA_IN(x);
	for(i=0;i<8;i++){
		DRV_IIC_SCL_CLR(x);
		Delay_us(4);
		DRV_IIC_SCL_SET(x);
		receive<<=1;
		if(DRV_IIC_SDA_READ(x)) receive++;
		Delay_us(4);
	}
	if(!ack){
		DRV_IIC_NAck(x);
	}
	else {
		DRV_IIC_Ack(x);
	}
	return receive;
}

//return value:0 SUCCESS,1 ERROR
int8_t drv_i2c_register(uint32_t scl_pin,uint32_t sda_pin,Drv_I2c_Bus *i2c_bus){
    int8_t index = -1;
	uint8_t i = 0;
	for(i=0;i<DRV_MAX_IIC_BUS_NUM;i++){
		if(drv_i2c_bus[i].regsitered == 0){//Not registered
			drv_i2c_bus[i].regsitered 	= 1;
			drv_i2c_bus[i].scl_pin 		= scl_pin;
			drv_i2c_bus[i].sda_pin 		= sda_pin;
			i2c_bus->scl_pin			= scl_pin;
			i2c_bus->sda_pin			= sda_pin;
			i2c_bus->start 				= DRV_IIC_START;
			i2c_bus->stop  				= DRV_IIC_STOP;
			i2c_bus->wait_ask 			= DRV_IIC_Wait_Ack;
			i2c_bus->ask      			= DRV_IIC_Ack;
			i2c_bus->nask     			= DRV_IIC_NAck;
			i2c_bus->send_byte 			= DRV_IIC_SEND_BYTE;
			i2c_bus->read_byte 			= DRV_IIC_READ_BYTE;
			hc32_pin_mode(scl_pin,PIN_MODE_OUTPUT_PULLUP);
			hc32_pin_mode(sda_pin,PIN_MODE_OUTPUT_PULLUP);
			hc32_pin_write(scl_pin,PIN_HIGH);
			hc32_pin_write(sda_pin,PIN_HIGH);
			index = i;
			
			break;
		} 
	}
	if(index == -1){
		printf("drv_i2c_register failed!\n");
	}
	
	//rt_mutex_release(&i2c_bus_lock);
	return index;
}

int8_t drv_i2c_destory(Drv_I2c_Bus *i2c_bus){
	int8_t index = -1;
	uint8_t i = 0;
	for(i=0;i<DRV_MAX_IIC_BUS_NUM;i++){
		if(i2c_bus->scl_pin == drv_i2c_bus[i].scl_pin && i2c_bus->sda_pin == drv_i2c_bus[i].sda_pin){
			drv_i2c_bus[i].regsitered 	= 0;
			drv_i2c_bus[i].scl_pin 		= 0;
			drv_i2c_bus[i].sda_pin 		= 0;
			i2c_bus->scl_pin			= 0;
			i2c_bus->sda_pin			= 0;
			i2c_bus->start 				= NULL;
			i2c_bus->stop  				= NULL;
			i2c_bus->wait_ask 			= NULL;
			i2c_bus->ask      			= NULL;
			i2c_bus->nask     			= NULL;
			i2c_bus->send_byte 			= NULL;
			i2c_bus->read_byte 			= NULL;
			index = 0;
			break;
		}
	}
	if(index == -1){
		printf("drv_i2c_destory failed!\n");
	}
	return index;
}

void drv_i2c_init(void){

}

